/******************************************************************************
 * Copyright (C) 2015  671643387@qq.com
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *****************************************************************************/

#ifndef SHARED_DB_CALLBACK_H_
#define SHARED_DB_CALLBACK_H_

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif

namespace Shared {
namespace DB {
    class QueryResult;


    ///////////////////////////////////////////////////////////////////////
    template<class Class, typename ParamType1, typename ParamType2>
    class _Callback
    {
    protected:
        typedef void (Class::*Method)(ParamType1, ParamType2);
        Class* _object;
        Method _method;
        ParamType1 _param1;
        ParamType2 _param2;
        void execute_() { (_object->*_method)(_param1, _param2); }

    public:
        _Callback(Class* object, Method method, ParamType1 param1, ParamType2 param2)
            : _object(object), _method(method),
            _param1(param1), _param2(param2)
        {
        }

        _Callback(_Callback<Class, ParamType1, ParamType2> const& cb)
            : _object(cb._object), _method(cb._method),
            _param1(cb._param1), _param2(cb._param2)
        {
        }
    };


    ///////////////////////////////////////////////////////////////////////
    class IQueryCallback
    {
    public:
        virtual void execute() = 0;
        virtual ~IQueryCallback() {}

        virtual void setResult(QueryResult* result) = 0;
        virtual QueryResult* getResult() = 0;
    };

    template<class CB>
    class _IQueryCallback : public CB, public IQueryCallback
    {
    public:
        _IQueryCallback(CB const& cb) : CB(cb)
        {
        }

        void execute() { CB::execute_(); }
        void setResult(QueryResult* result) { CB::_param1 = result; }
        QueryResult* getResult() { return CB::_param1; }
    };


    ///////////////////////////////////////////////////////////////////////
    template<class Class, typename ParamType1>
    class QueryCallback : public _IQueryCallback<_Callback<Class, QueryResult*, ParamType1> >
    {
    private:
        typedef _Callback<Class, QueryResult*, ParamType1> QC1;

    public:
        QueryCallback(Class* object, typename QC1::Method method, QueryResult* result, ParamType1 param1)
            : _IQueryCallback<QC1>(QC1(object, method, result, param1))
        {
        }
    };

}}

#endif // SHARED_DB_CALLBACK_H_
